<!DOCTYPE html>
<html>

<head>
  <title>Quarkus - Writing JSON REST Services</title>
  <script id="adobe_dtm" src="https://www.redhat.com/dtm.js" type="text/javascript"></script>
  <script src="/assets/javascript/highlight.pack.js" type="text/javascript"></script>
  <META HTTP-EQUIV='Content-Security-Policy' CONTENT="default-src 'none'; script-src 'self' 'unsafe-eval' 'sha256-ANpuoVzuSex6VhqpYgsG25OHWVA1I+F6aGU04LoI+5s=' 'sha256-ipy9P/3rZZW06mTLAR0EnXvxSNcnfSDPLDuh3kzbB1w=' js.bizographics.com https://www.redhat.com assets.adobedtm.com jsonip.com https://ajax.googleapis.com https://www.googletagmanager.com https://www.google-analytics.com https://use.fontawesome.com; style-src 'self' https://fonts.googleapis.com https://use.fontawesome.com; img-src 'self' *; media-src 'self' ; frame-src https://www.googletagmanager.com https://www.youtube.com; frame-ancestors 'none'; base-uri 'none'; object-src 'none'; form-action 'none'; font-src 'self' https://use.fontawesome.com https://fonts.gstatic.com;">
  <META HTTP-EQUIV='X-Frame-Options' CONTENT="DENY">
  <META HTTP-EQUIV='X-XSS-Protection' CONTENT="1; mode=block">
  <META HTTP-EQUIV='X-Content-Type-Options' CONTENT="nosniff">
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="description" content="Quarkus: Supersonic Subatomic Java">
  <meta name="twitter:card" content="summary_large_image">
  <meta name="twitter:site" content="@QuarkusIO"> 
  <meta name="twitter:creator" content="@QuarkusIO">
  <meta property="og:url" content="https://quarkus.io/guides/rest-json" />
  <meta property="og:title" content="Quarkus - Writing JSON REST Services" />
  <meta property="og:description" content="Quarkus: Supersonic Subatomic Java" />
  <meta property="og:image" content="/assets/images/quarkus_card.png" />
  <link rel="canonical" href="https://quarkus.io/guides/rest-json">
  <link rel="shortcut icon" type="image/png" href="/favicon.ico" >
  <link rel="stylesheet" href="https://quarkus.io/guides/stylesheet/config.css" />
  <link rel="stylesheet" href="/assets/css/main.css" />
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css" integrity="sha384-lKuwvrZot6UHsBSfcMvOkWwlCMgc0TaWr+30HWe3a4ltaBwTZhyTEggF5tJv8tbt" crossorigin="anonymous">
  <link rel="alternate" type="application/rss+xml"  href="https://quarkus.io/feed.xml" title="Quarkus">
  <script src="https://quarkus.io/assets/javascript/goan.js" type="text/javascript"></script>
  <script src="https://quarkus.io/assets/javascript/hl.js" type="text/javascript"></script>
</head>

<body class="guides">
  <!-- Google Tag Manager (noscript) -->
  <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-NJWS5L"
  height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
  <!-- End Google Tag Manager (noscript) -->

  <div class="nav-wrapper">
  <div class="grid-wrapper">
    <div class="width-12-12">
      <input type="checkbox" id="checkbox" />
      <nav id="main-nav" class="main-nav">
  <div class="container">
    <div class="logo-wrapper">
      
        <a href="/"><img src="/assets/images/quarkus_logo_horizontal_rgb_600px_reverse.png" class="project-logo" title="Quarkus"></a>
      
    </div>
    <label class="nav-toggle" for="checkbox">
      <i class="fa fa-bars"></i>
    </label>
    <div id="menu" class="menu">
      <span>
        <a href="/get-started/" class="">Get Started</a>
      </span>
      <span>
        <a href="/guides/" class="active">Guides</a>
      </span>
      <span>
        <a href="/community/" class="">Community</a>
      </span>
      <span>
        <a href="/support/" class="">Support</a>
      </span>
      <span>
        <a href="/blog/" class="">Blog</a>
      </span>
      <span>
        <a href="https://code.quarkus.io" class="button-cta secondary white">Start Coding</a>
      </span>
    </div>
  </div>
      </nav>
    </div>
  </div>
</div>

  <div class="content">
    <div class="guide">
  <div class="width-12-12">
    <h1 class="text-caps">Quarkus - Writing JSON REST Services</h1>
    <div class="hide-mobile toc"><ul class="sectlevel1">
<li><a href="#prerequisites">Prerequisites</a></li>
<li><a href="#architecture">Architecture</a></li>
<li><a href="#solution">Solution</a></li>
<li><a href="#creating-the-maven-project">Creating the Maven project</a></li>
<li><a href="#creating-your-first-json-rest-service">Creating your first JSON REST service</a>
<ul class="sectlevel2">
<li><a href="#configuring-json-support">Configuring JSON support</a></li>
</ul>
</li>
<li><a href="#creating-a-frontend">Creating a frontend</a></li>
<li><a href="#building-a-native-executable">Building a native executable</a></li>
<li><a href="#about-serialization">About serialization</a></li>
<li><a href="#using-response">Using Response</a></li>
<li><a href="#reactive">Being reactive</a></li>
<li><a href="#http-filters-and-interceptors">HTTP filters and interceptors</a></li>
<li><a href="#cors-filter">CORS filter</a></li>
<li><a href="#gzip-support">GZip Support</a></li>
<li><a href="#servlet-compatibility">Servlet compatibility</a></li>
<li><a href="#whats-different-from-jakarta-ee-development">What&#8217;s Different from Jakarta EE Development</a>
<ul class="sectlevel2">
<li><a href="#no-need-for-application-class">No Need for <code>Application</code> Class</a></li>
<li><a href="#lifecycle-of-resources">Lifecycle of Resources</a></li>
</ul>
</li>
<li><a href="#conclusion">Conclusion</a></li>
</ul></div>
    <div>
      <div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>JSON is now the <em>lingua franca</em> between microservices.</p>
</div>
<div class="paragraph">
<p>In this guide, we see how you can get your REST services to consume and produce JSON payloads.</p>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
there is another guide if you need a <a href="rest-client">REST client</a> (including support for JSON).
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="prerequisites"><a class="anchor" href="#prerequisites"></a>Prerequisites</h2>
<div class="sectionbody">
<div class="paragraph">
<p>To complete this guide, you need:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>less than 15 minutes</p>
</li>
<li>
<p>an IDE</p>
</li>
<li>
<p>JDK 1.8+ installed with <code>JAVA_HOME</code> configured appropriately</p>
</li>
<li>
<p>Apache Maven 3.6.2+</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="architecture"><a class="anchor" href="#architecture"></a>Architecture</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The application built in this guide is quite simple: the user can add elements in a list using a form and the list is updated.</p>
</div>
<div class="paragraph">
<p>All the information between the browser and the server are formatted as JSON.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="solution"><a class="anchor" href="#solution"></a>Solution</h2>
<div class="sectionbody">
<div class="paragraph">
<p>We recommend that you follow the instructions in the next sections and create the application step by step.
However, you can go right to the completed example.</p>
</div>
<div class="paragraph">
<p>Clone the Git repository: <code>git clone <a href="https://github.com/quarkusio/quarkus-quickstarts.git" class="bare">https://github.com/quarkusio/quarkus-quickstarts.git</a></code>, or download an <a href="https://github.com/quarkusio/quarkus-quickstarts/archive/master.zip">archive</a>.</p>
</div>
<div class="paragraph">
<p>The solution is located in the <code>rest-json-quickstart</code> <a href="https://github.com/quarkusio/quarkus-quickstarts/tree/master/rest-json-quickstart">directory</a>.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="creating-the-maven-project"><a class="anchor" href="#creating-the-maven-project"></a>Creating the Maven project</h2>
<div class="sectionbody">
<div class="paragraph">
<p>First, we need a new project. Create a new project with the following command:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">mvn io.quarkus:quarkus-maven-plugin:1.7.0.Final:create \
    -DprojectGroupId=org.acme \
    -DprojectArtifactId=rest-json-quickstart \
    -DclassName="org.acme.rest.json.FruitResource" \
    -Dpath="/fruits" \
    -Dextensions="resteasy-jsonb"
cd rest-json-quickstart</code></pre>
</div>
</div>
<div class="paragraph">
<p>This command generates a Maven structure importing the RESTEasy/JAX-RS and <a href="http://json-b.net/">JSON-B</a> extensions,
and in particular adds the following dependency:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="xml" class="language-xml hljs">&lt;dependency&gt;
    &lt;groupId&gt;io.quarkus&lt;/groupId&gt;
    &lt;artifactId&gt;quarkus-resteasy-jsonb&lt;/artifactId&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Quarkus also supports <a href="https://github.com/FasterXML/jackson">Jackson</a> so, if you prefer Jackson over JSON-B, you can create a project relying on the RESTEasy Jackson extension instead:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">mvn io.quarkus:quarkus-maven-plugin:1.7.0.Final:create \
    -DprojectGroupId=org.acme \
    -DprojectArtifactId=rest-json-quickstart \
    -DclassName="org.acme.rest.json.FruitResource" \
    -Dpath="/fruits" \
    -Dextensions="resteasy-jackson"
cd rest-json-quickstart</code></pre>
</div>
</div>
<div class="paragraph">
<p>This command generates a Maven structure importing the RESTEasy/JAX-RS and <a href="https://github.com/FasterXML/jackson">Jackson</a> extensions,
and in particular adds the following dependency:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="xml" class="language-xml hljs">&lt;dependency&gt;
    &lt;groupId&gt;io.quarkus&lt;/groupId&gt;
    &lt;artifactId&gt;quarkus-resteasy-jackson&lt;/artifactId&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>To improve user experience, Quarkus registers the three Jackson <a href="https://github.com/FasterXML/jackson-modules-java8">Java 8 modules</a> so you don&#8217;t need to do it manually.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="creating-your-first-json-rest-service"><a class="anchor" href="#creating-your-first-json-rest-service"></a>Creating your first JSON REST service</h2>
<div class="sectionbody">
<div class="paragraph">
<p>In this example, we will create an application to manage a list of fruits.</p>
</div>
<div class="paragraph">
<p>First, let&#8217;s create the <code>Fruit</code> bean as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">package org.acme.rest.json;

public class Fruit {

    public String name;
    public String description;

    public Fruit() {
    }

    public Fruit(String name, String description) {
        this.name = name;
        this.description = description;
    }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Nothing fancy. One important thing to note is that having a default constructor is required by the JSON serialization layer.</p>
</div>
<div class="paragraph">
<p>Now, edit the <code>org.acme.rest.json.FruitResource</code> class as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">package org.acme.rest.json;

import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Set;

import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/fruits")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class FruitResource {

    private Set&lt;Fruit&gt; fruits = Collections.newSetFromMap(Collections.synchronizedMap(new LinkedHashMap&lt;&gt;()));

    public FruitResource() {
        fruits.add(new Fruit("Apple", "Winter fruit"));
        fruits.add(new Fruit("Pineapple", "Tropical fruit"));
    }

    @GET
    public Set&lt;Fruit&gt; list() {
        return fruits;
    }

    @POST
    public Set&lt;Fruit&gt; add(Fruit fruit) {
        fruits.add(fruit);
        return fruits;
    }

    @DELETE
    public Set&lt;Fruit&gt; delete(Fruit fruit) {
        fruits.removeIf(existingFruit -&gt; existingFruit.name.contentEquals(fruit.name));
        return fruits;
    }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The implementation is pretty straightforward and you just need to define your endpoints using the JAX-RS annotations.</p>
</div>
<div class="paragraph">
<p>The <code>Fruit</code> objects will be automatically serialized/deserialized by <a href="http://json-b.net/">JSON-B</a> or <a href="https://github.com/FasterXML/jackson">Jackson</a>,
depending on the extension you chose when initializing the project.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p>While RESTEasy supports auto-negotiation, when using Quarkus, it is very important to define the <code>@Produces</code> and <code>@Consumes</code> annotations.
They are analyzed at build time and Quarkus restricts the number of JAX-RS providers included in the native executable to the minimum required by the application.
It allows to reduce the size of the native executable.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="sect2">
<h3 id="configuring-json-support"><a class="anchor" href="#configuring-json-support"></a>Configuring JSON support</h3>
<div class="sect3">
<h4 id="json-b"><a class="anchor" href="#json-b"></a>JSON-B</h4>
<div class="paragraph">
<p>Quarkus makes it very easy to configure various JSON-B settings via CDI beans. The simplest (and suggested) approach is to define a CDI bean of type <code>io.quarkus.jsonb.JsonbConfigCustomizer</code>
inside of which any JSON-B configuration can be applied.</p>
</div>
<div class="paragraph">
<p>If for example a custom serializer named <code>FooSerializer</code> for type <code>com.example.Foo</code> needs to be registered with JSON-B, the addition of a bean like the following would suffice:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">import io.quarkus.jsonb.JsonbConfigCustomizer;
import javax.inject.Singleton;
import javax.json.bind.JsonbConfig;
import javax.json.bind.serializer.JsonbSerializer;

@Singleton
public class FooSerializerRegistrationCustomizer implements JsonbConfigCustomizer {

    public void customize(JsonbConfig config) {
        config.withSerializers(new FooSerializer());
    }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>A more advanced option would be to directly provide a bean of <code>javax.json.bind.JsonbConfig</code> (with a <code>Dependent</code> scope) or in the extreme case to provide a bean of type <code>javax.json.bind.Jsonb</code> (with a <code>Singleton</code> scope).
If the latter approach is leveraged it is very important to manually inject and apply all <code>io.quarkus.jsonb.JsonbConfigCustomizer</code> beans in the CDI producer that produces <code>javax.json.bind.Jsonb</code>.
Failure to do so will prevent JSON-B specific customizations provided by various extensions from being applied.</p>
</div>
</div>
<div class="sect3">
<h4 id="jackson"><a class="anchor" href="#jackson"></a>Jackson</h4>
<div class="paragraph">
<p>As stated above, Quarkus provides the option of using <a href="https://github.com/FasterXML/jackson">Jackson</a> instead of JSON-B via the use of the <code>quarkus-resteasy-jackson</code> extension.</p>
</div>
<div class="paragraph">
<p>Following the same approach as described in the previous section, Jackson&#8217;s <code>ObjectMapper</code> can be configured using a <code>io.quarkus.jackson.ObjectMapperCustomizer</code> bean.
An example where a custom module needs to be registered would like so:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">import com.fasterxml.jackson.databind.ObjectMapper;
import io.quarkus.jackson.ObjectMapperCustomizer;
import javax.inject.Singleton;

@Singleton
public class RegisterCustomModuleCustomizer implements ObjectMapperCustomizer {

    public void customize(ObjectMapper mapper) {
        mapper.registerModule(new CustomModule());
    }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Users can even provide their own <code>ObjectMapper</code> bean if they so choose.
If this is done, it is very important to manually inject and apply all <code>io.quarkus.jackson.ObjectMapperCustomizer</code> beans in the CDI producer that produces <code>ObjectMapper</code>.
Failure to do so will prevent Jackson specific customizations provided by various extensions from being applied.</p>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="creating-a-frontend"><a class="anchor" href="#creating-a-frontend"></a>Creating a frontend</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Now let&#8217;s add a simple web page to interact with our <code>FruitResource</code>.
Quarkus automatically serves static resources located under the <code>META-INF/resources</code> directory.
In the <code>src/main/resources/META-INF/resources</code> directory, add a <code>fruits.html</code> file with the content from this <a href="https://github.com/quarkusio/quarkus-quickstarts/blob/master/rest-json-quickstart/src/main/resources/META-INF/resources/fruits.html">fruits.html</a> file in it.</p>
</div>
<div class="paragraph">
<p>You can now interact with your REST service:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>start Quarkus with <code>./mvnw compile quarkus:dev</code></p>
</li>
<li>
<p>open a browser to <code><a href="http://localhost:8080/fruits.html" class="bare">http://localhost:8080/fruits.html</a></code></p>
</li>
<li>
<p>add new fruits to the list via the form</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="building-a-native-executable"><a class="anchor" href="#building-a-native-executable"></a>Building a native executable</h2>
<div class="sectionbody">
<div class="paragraph">
<p>You can build a native executable with the usual command <code>./mvnw package -Pnative</code>.</p>
</div>
<div class="paragraph">
<p>Running it is as simple as executing <code>./target/rest-json-quickstart-1.0-SNAPSHOT-runner</code>.</p>
</div>
<div class="paragraph">
<p>You can then point your browser to <code><a href="http://localhost:8080/fruits.html" class="bare">http://localhost:8080/fruits.html</a></code> and use your application.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="about-serialization"><a class="anchor" href="#about-serialization"></a>About serialization</h2>
<div class="sectionbody">
<div class="paragraph">
<p>JSON serialization libraries use Java reflection to get the properties of an object and serialize them.</p>
</div>
<div class="paragraph">
<p>When using native executables with GraalVM, all classes that will be used with reflection need to be registered.
The good news is that Quarkus does that work for you most of the time.
So far, we haven&#8217;t registered any class, not even <code>Fruit</code>, for reflection usage and everything is working fine.</p>
</div>
<div class="paragraph">
<p>Quarkus performs some magic when it is capable of inferring the serialized types from the REST methods.
When you have the following REST method, Quarkus determines that <code>Fruit</code> will be serialized:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="JAVA" class="language-JAVA hljs">@GET
@Produces("application/json")
public List&lt;Fruit&gt; list() {
    // ...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Quarkus does that for you automatically by analyzing the REST methods at build time
and that&#8217;s why we didn&#8217;t need any reflection registration in the first part of this guide.</p>
</div>
<div class="paragraph">
<p>Another common pattern in the JAX-RS world is to use the <code>Response</code> object.
<code>Response</code> comes with some nice perks:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>you can return different entity types depending on what happens in your method (a <code>Legume</code> or an <code>Error</code> for instance);</p>
</li>
<li>
<p>you can set the attributes of the <code>Response</code> (the status comes to mind in the case of an error).</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Your REST method then looks like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="JAVA" class="language-JAVA hljs">@GET
@Produces("application/json")
public Response list() {
    // ...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>It is not possible for Quarkus to determine at build time the type included in the <code>Response</code> as the information is not available.
In this case, Quarkus won&#8217;t be able to automatically register for reflection the required classes.</p>
</div>
<div class="paragraph">
<p>This leads us to our next section.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="using-response"><a class="anchor" href="#using-response"></a>Using Response</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Let&#8217;s create the <code>Legume</code> class which will be serialized as JSON, following the same model as for our <code>Fruit</code> class:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="JAVA" class="language-JAVA hljs">package org.acme.rest.json;

public class Legume {

    public String name;
    public String description;

    public Legume() {
    }

    public Legume(String name, String description) {
        this.name = name;
        this.description = description;
    }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Now let&#8217;s create a <code>LegumeResource</code> REST service with only one method which returns the list of legumes.</p>
</div>
<div class="paragraph">
<p>This method returns a <code>Response</code> and not a list of <code>Legume</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="JAVA" class="language-JAVA hljs">package org.acme.rest.json;

import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;

import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

@Path("/legumes")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class LegumeResource {

    private Set&lt;Legume&gt; legumes = Collections.synchronizedSet(new LinkedHashSet&lt;&gt;());

    public LegumeResource() {
        legumes.add(new Legume("Carrot", "Root vegetable, usually orange"));
        legumes.add(new Legume("Zucchini", "Summer squash"));
    }

    @GET
    public Response list() {
        return Response.ok(legumes).build();
    }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Now let&#8217;s add a simple web page to display our list of legumes.
In the <code>src/main/resources/META-INF/resources</code> directory, add a <code>legumes.html</code> file with the content from this
<a href="https://github.com/quarkusio/quarkus-quickstarts/blob/master/rest-json-quickstart/src/main/resources/META-INF/resources/legumes.html">legumes.html</a> file in it.</p>
</div>
<div class="paragraph">
<p>Open a browser to <a href="http://localhost:8080/legumes.html" class="bare">http://localhost:8080/legumes.html</a> and you will see our list of legumes.</p>
</div>
<div class="paragraph">
<p>The interesting part starts when running the application as a native executable:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>create the native executable with <code>./mvnw package -Pnative</code>.</p>
</li>
<li>
<p>execute it with <code>./target/rest-json-quickstart-1.0-SNAPSHOT-runner</code></p>
</li>
<li>
<p>open a browser and go to <a href="http://localhost:8080/legumes.html" class="bare">http://localhost:8080/legumes.html</a></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>No legumes there.</p>
</div>
<div class="paragraph">
<p>As mentioned above, the issue is that Quarkus was not able to determine the <code>Legume</code> class will require some reflection by analyzing the REST endpoints.
The JSON serialization library tries to get the list of fields of <code>Legume</code> and gets an empty list so it does not serialize the fields' data.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p>At the moment, when JSON-B or Jackson tries to get the list of fields of a class, if the class is not registered for reflection, no exception will be thrown.
GraalVM will simply return an empty list of fields.</p>
</div>
<div class="paragraph">
<p>Hopefully, this will change in the future and make the error more obvious.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>We can register <code>Legume</code> for reflection manually by adding the <code>@RegisterForReflection</code> annotation on our <code>Legume</code> class:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="JAVA" class="language-JAVA hljs">import io.quarkus.runtime.annotations.RegisterForReflection;

@RegisterForReflection
public class Legume {
    // ...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Let&#8217;s do that and follow the same steps as before:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>hit <code>Ctrl+C</code> to stop the application</p>
</li>
<li>
<p>create the native executable with <code>./mvnw package -Pnative</code>.</p>
</li>
<li>
<p>execute it with <code>./target/rest-json-quickstart-1.0-SNAPSHOT-runner</code></p>
</li>
<li>
<p>open a browser and go to <a href="http://localhost:8080/legumes.html" class="bare">http://localhost:8080/legumes.html</a></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>This time, you can see our list of legumes.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="reactive"><a class="anchor" href="#reactive"></a>Being reactive</h2>
<div class="sectionbody">
<div class="paragraph">
<p>You can return <em>reactive types</em> to handle asynchronous processing.
Quarkus recommends the usage of <a href="https://smallrye.io/smallrye-mutiny">Mutiny</a> to write reactive and asynchronous code.</p>
</div>
<div class="paragraph">
<p>To integrate Mutiny and RESTEasy, you need to add the <code>quarkus-resteasy-mutiny</code> dependency to your project:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="xml" class="language-xml hljs">&lt;dependency&gt;
  &lt;groupId&gt;io.quarkus&lt;/groupId&gt;
  &lt;artifactId&gt;quarkus-resteasy-mutiny&lt;/artifactId&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Then, your endpoint can return <code>Uni</code> or <code>Multi</code> instances:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">@GET
@Path("/{name}")
public Uni&lt;Fruit&gt; getOne(@PathParam String name) {
    return findByName(name);
}

@GET
public Multi&lt;Fruit&gt; getAll() {
    return findAll();
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Use <code>Uni</code> when you have a single result.
Use <code>Multi</code> when you have multiple items that may be emitted asynchronously.</p>
</div>
<div class="paragraph">
<p>You can use <code>Uni</code> and <code>Response</code> to return asynchronous HTTP responses: <code>Uni&lt;Response&gt;</code>.</p>
</div>
<div class="paragraph">
<p>More details about Mutiny can be found in the <a href="getting-started-reactive#mutiny">Getting Started with Reactive guide</a>.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="http-filters-and-interceptors"><a class="anchor" href="#http-filters-and-interceptors"></a>HTTP filters and interceptors</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Both HTTP request and response can be intercepted by providing <code>ContainerRequestFilter</code> or <code>ContainerResponseFilter</code>
implementations respectively. These filters are suitable for processing the metadata associated with a message: HTTP
headers, query parameters, media type, and other metadata. They also have the capability to abort the request
processing, for instance when the user does not have the permissions to access the endpoint.</p>
</div>
<div class="paragraph">
<p>Let&#8217;s use <code>ContainerRequestFilter</code> to add logging capability to our service. We can do that by implementing
<code>ContainerRequestFilter</code> and annotating it with the <code>@Provider</code> annotation:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">package org.acme.rest.json;

import io.vertx.core.http.HttpServerRequest;
import org.jboss.logging.Logger;

import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.UriInfo;
import javax.ws.rs.ext.Provider;

@Provider
public class LoggingFilter implements ContainerRequestFilter {

    private static final Logger LOG = Logger.getLogger(LoggingFilter.class);

    @Context
    UriInfo info;

    @Context
    HttpServerRequest request;

    @Override
    public void filter(ContainerRequestContext context) {

        final String method = context.getMethod();
        final String path = info.getPath();
        final String address = request.remoteAddress().toString();

        LOG.infof("Request %s %s from IP %s", method, path, address);
    }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Now, whenever a REST method is invoked, the request will be logged into the console:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">2019-06-05 12:44:26,526 INFO  [org.acm.res.jso.LoggingFilter] (executor-thread-1) Request GET /legumes from IP 127.0.0.1
2019-06-05 12:49:19,623 INFO  [org.acm.res.jso.LoggingFilter] (executor-thread-1) Request GET /fruits from IP 0:0:0:0:0:0:0:1
2019-06-05 12:50:44,019 INFO  [org.acm.res.jso.LoggingFilter] (executor-thread-1) Request POST /fruits from IP 0:0:0:0:0:0:0:1
2019-06-05 12:51:04,485 INFO  [org.acm.res.jso.LoggingFilter] (executor-thread-1) Request GET /fruits from IP 127.0.0.1</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="cors-filter"><a class="anchor" href="#cors-filter"></a>CORS filter</h2>
<div class="sectionbody">
<div class="paragraph">
<p><a href="https://en.wikipedia.org/wiki/Cross-origin_resource_sharing">Cross-origin resource sharing</a> (CORS) is a mechanism that
allows restricted resources on a web page to be requested from another domain outside the domain from which the first resource
was served.</p>
</div>
<div class="paragraph">
<p>Quarkus comes with a CORS filter. Read the <a href="http-reference#cors-filter">HTTP Reference Documentation</a> to learn
how to use it.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="gzip-support"><a class="anchor" href="#gzip-support"></a>GZip Support</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Quarkus comes with GZip support (even though it is not enabled by default). The following configuration knobs allow to configure GZip support.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="properties" class="language-properties hljs">quarkus.resteasy.gzip.enabled=true <i class="conum" data-value="1"></i><b>(1)</b>
quarkus.resteasy.gzip.max-input=10M <i class="conum" data-value="2"></i><b>(2)</b></code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>Enable Gzip support.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>Configure the upper limit on deflated request body. This is useful to mitigate potential attacks by limiting their reach. The default value is <code>10M</code>.
This configuration option would recognize strings in this format (shown as a regular expression): <code>[0-9]+[KkMmGgTtPpEeZzYy]?</code>. If no suffix is given, assume bytes.</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="servlet-compatibility"><a class="anchor" href="#servlet-compatibility"></a>Servlet compatibility</h2>
<div class="sectionbody">
<div class="paragraph">
<p>In Quarkus, RESTEasy can either run directly on top of the Vert.x HTTP server, or on top of Undertow if you have any servlet dependency.</p>
</div>
<div class="paragraph">
<p>As a result, certain classes, such as <code>HttpServletRequest</code> are not always available for injection. Most use-cases for this particular
class are covered by JAX-RS equivalents, except for getting the remote client&#8217;s IP. RESTEasy comes with a replacement API which you can inject:
<a href="https://docs.jboss.org/resteasy/docs/4.4.2.Final/javadocs/org/jboss/resteasy/spi/HttpRequest.html"><code>HttpRequest</code></a>, which has the methods
<a href="https://docs.jboss.org/resteasy/docs/4.4.2.Final/javadocs/org/jboss/resteasy/spi/HttpRequest.html#getRemoteAddress--"><code>getRemoteAddress()</code></a>
and <a href="https://docs.jboss.org/resteasy/docs/4.4.2.Final/javadocs/org/jboss/resteasy/spi/HttpRequest.html#getRemoteHost--"><code>getRemoteHost()</code></a>
to solve this problem.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="whats-different-from-jakarta-ee-development"><a class="anchor" href="#whats-different-from-jakarta-ee-development"></a>What&#8217;s Different from Jakarta EE Development</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="no-need-for-application-class"><a class="anchor" href="#no-need-for-application-class"></a>No Need for <code>Application</code> Class</h3>
<div class="paragraph">
<p>Configuration via an application-supplied subclass of <code>Application</code> is supported, but not required.</p>
</div>
</div>
<div class="sect2">
<h3 id="lifecycle-of-resources"><a class="anchor" href="#lifecycle-of-resources"></a>Lifecycle of Resources</h3>
<div class="paragraph">
<p>In Quarkus all JAX-RS resources are treated as CDI beans.
It&#8217;s possible to inject other beans via <code>@Inject</code>, bind interceptors using bindings such as <code>@Transactional</code>, define <code>@PostConstruct</code> callbacks, etc.</p>
</div>
<div class="paragraph">
<p>If there is no scope annotation declared on the resource class then the scope is defaulted.
The default scope can be controlled through the <code>quarkus.resteasy.singleton-resources</code> property.
If set to <code>true</code> (default) then a <strong>single instance</strong> of a resource class is created to service all requests (as defined by <code>@javax.inject.Singleton</code>).
If set to <code>false</code> then a <strong>new instance</strong> of the resource class is created per each request.
An explicit CDI scope annotation (<code>@RequestScoped</code>, <code>@ApplicationScoped</code>, etc.) always overrides the default behavior and specifies the lifecycle of resource instances.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="conclusion"><a class="anchor" href="#conclusion"></a>Conclusion</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Creating JSON REST services with Quarkus is easy as it relies on proven and well known technologies.</p>
</div>
<div class="paragraph">
<p>As usual, Quarkus further simplifies things under the hood when running your application as a native executable.</p>
</div>
<div class="paragraph">
<p>There is only one thing to remember: if you use <code>Response</code> and Quarkus can&#8217;t determine the beans that are serialized, you need to annotate them with <code>@RegisterForReflection</code>.</p>
</div>
</div>
</div>
    </div>
  </div>
</div>

  </div>

  <div class="content project-footer">
  <div class="footer-section">
    <div class="logo-wrapper">
      <a href="/"><img src="/assets/images/quarkus_logo_horizontal_rgb_reverse.svg" class="project-logo" title="Quarkus"></a>
    </div>
  </div>
  <div class="grid-wrapper">
    <p class="grid__item width-3-12">Quarkus is open. All dependencies of this project are available under the <a href='https://www.apache.org/licenses/LICENSE-2.0' target='_blank'>Apache Software License 2.0</a> or compatible license.<br /><br />This website was built with <a href='https://jekyllrb.com/' target='_blank'>Jekyll</a>, is hosted on <a href='https://pages.github.com/' target='_blank'>Github Pages</a> and is completely open source. If you want to make it better, <a href='https://github.com/quarkusio/quarkusio.github.io' target='_blank'>fork the website</a> and show us what you’ve got.</p>

    
      <div class="width-1-12 project-links">
        <span>Navigation</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="/">Home</a></li>
          
            <li><a href="/guides">Guides</a></li>
          
            <li><a href="/community/#contributing">Contribute</a></li>
          
            <li><a href="/faq">FAQ</a></li>
          
            <li><a href="/get-started">Get Started</a></li>
          
        </ul>
      </div>
    
      <div class="width-1-12 project-links">
        <span>Contribute</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="https://twitter.com/quarkusio">Follow us</a></li>
          
            <li><a href="https://github.com/quarkusio">GitHub</a></li>
          
            <li><a href="/security">Security&nbsp;policy</a></li>
          
        </ul>
      </div>
    
      <div class="width-1-12 project-links">
        <span>Get Help</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="https://groups.google.com/forum/#!forum/quarkus-dev">Forums</a></li>
          
            <li><a href="https://quarkusio.zulipchat.com">Chatroom</a></li>
          
        </ul>
      </div>
    

    
      <div class="width-3-12 more-links">
        <span>Quarkus is made of community projects</span>
        <ul class="footer-links">
          
            <li><a href="https://vertx.io/" target="_blank">Eclipse Vert.x</a></li>
          
            <li><a href="https://microprofile.io" target="_blank">Eclipse MicroProfile</a></li>
          
            <li><a href="https://hibernate.org" target="_blank">Hibernate</a></li>
          
            <li><a href="https://netty.io" target="_blank">Netty</a></li>
          
            <li><a href="https://resteasy.github.io" target="_blank">RESTEasy</a></li>
          
            <li><a href="https://camel.apache.org" target="_blank">Apache Camel</a></li>
          
            <li><a href="https://code.quarkus.io/" target="_blank">And many more...</a></li>
          
        </ul>
      </div>
    
  </div>
</div>
  <div class="content redhat-footer">
  <div class="grid-wrapper">
    <span class="licence">
      <i class="fab fa-creative-commons"></i><i class="fab fa-creative-commons-by"></i> <a href="https://creativecommons.org/licenses/by/3.0/" target="_blank">CC by 3.0</a> | <a href="https://www.redhat.com/en/about/privacy-policy">Privacy Policy</a>
    </span>
    <span class="redhat">
      Sponsored by
    </span>
    <span class="redhat-logo">
      <a href="https://www.redhat.com/" target="_blank"><img src="/assets/images/redhat_reversed.svg"></a>
    </span>
  </div>
</div>


  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js" integrity="sha384-8gBf6Y4YYq7Jx97PIqmTwLPin4hxIzQw5aDmUg/DDhul9fFpbbLcLh3nTIIDJKhx" crossorigin="anonymous"></script>
  <script type="text/javascript" src="/assets/javascript/mobile-nav.js"></script>
  <script type="text/javascript" src="/assets/javascript/scroll-down.js"></script>
  <script src="/assets/javascript/satellite.js" type="text/javascript"></script>
  <script src="https://quarkus.io/guides/javascript/config.js" type="text/javascript"></script>
  <script src="/assets/javascript/search-filter.js" type="text/javascript"></script>
  <script src="/assets/javascript/back-to-top.js" type="text/javascript"></script>
</body>

</html>
